#pragma once

//#include "game_entity.h"
#include <stack>
#include <vector>
#include <assert.h>

struct Entity;

//const int game_dynamic_entity_size = 512;

struct EntityList 
{
	V2i chunk_id;


	//dynamic entity system//
	//Constant amount on entities so no create time needed.
	//check if ENTITY_INACTIVE to use entity retrieved from array
	
	/*
	std::stack<int> * _free_pos;
	std::map<int,int> * _taken_map;
	Entity _dynamics[game_dynamic_entity_size];

	Entity * addDynamic(Uint8 flags, Uint64 entID, V2 size, Uint8 spriteID, V2 pos, V2 vel)
	{
		if (!_free_pos->empty())
		{
			int index = _free_pos->top();
			_free_pos->pop();
			_dynamics[index].chunk_id = chunk_id;//e->chunk_id;
			_dynamics[index].flags = flags & (~ENTITY_INACTIVE);//e->flags  &  (~ENTITY_INACTIVE);
			_dynamics[index].id = entID;//e->id;
			_dynamics[index].size = size;//e->size;
			_dynamics[index].sprite_index = spriteID;
			_dynamics[index]._pos_ = pos;
			_dynamics[index]._velocity_ = vel;
			(*_taken_map)[entID] = index;
			return &_dynamics[index];
		}
		else
		{
			printf("dynamic is full\n");
			return NULL;
		}
	}

	void removeDynamic(Entity * e)
	{
		int index = (*_taken_map)[e->id];
		_dynamics[index].flags |= ENTITY_INACTIVE;
	}
	*/
	//end system


	std::vector<Entity*> * _vec;
	std::stack<Entity*> * _new;
	std::stack<Entity*> * _old;

	//copy constructor
	EntityList(const EntityList & other)
	{
		printf("EntityList copied!");
	}

	EntityList(V2i chunk_ID)
	{
		chunk_id = chunk_ID;
		_vec = new std::vector<Entity*>();
		_new = new std::stack<Entity*>();
		_old = new std::stack<Entity*>();

	}
	~EntityList()
	{
		delete _vec; delete _new;
		printf("EntityList destroyed!!\n");
	}
	void add(Entity * e)
	{
		//printf ("\tADD@[%d,%d]\n",chunk_id.x, chunk_id.y);
		//e->chunk_id = chunk_id;
		_new->push(e);
	}
	Entity * at(unsigned int index)
	{
		assert(index < _vec->size());
		return _vec->at(index);
	}

	void remove(Entity * e)
	{
		//printf (" remove@[%d,%d]",chunk_id.x, chunk_id.y);
		//e->chunk_id = v2i(-1,-1);
		this->_old->push(e);
	}

	Entity * operator [] (int index)
	{
		return at(index);
	}

	unsigned int size(){return _vec->size();}

	//Do not use this within a loop iterating over an entityList
	void ConsolidateList()
	{
		if (_new->size() >0 || _old->size() > 0)
		//printf("Consolidating [%d, %d]\n",this->chunk_id.x, chunk_id.y);
		while(_new->size() != 0)
		{
			//printf("CONS. adding entity to list\n");
			_vec->push_back(_new->top());
			_new->pop();
		}

		while(_old->size()!=0)
		{
			//printf("CONS. removing entity from list\n");

			//optimise this?//

			Entity * e = _old->top();	
			_old->pop();
			int vec_index = -1;
			for (int i = 0;i < _vec->size(); i++)
			{
				if (_vec->at(i) == e)
				{
					vec_index = i;
				}
			}
			if (vec_index != -1)
			{
				_vec->erase(_vec->cbegin() + vec_index);
			}
		}
	}
};

